home *** CD-ROM | disk | FTP | other *** search
/ HAM Radio 3.2 / Ham Radio Version 3.2 (Chestnut CD-ROMs)(1993).ISO / rtty / tlmdc / tlmdc.c < prev    next >
C/C++ Source or Header  |  1990-01-30  |  18KB  |  810 lines

  1. #include <stdio.h>
  2. #include <dos.h>
  3. #include <ctype.h>
  4. #include <time.h>
  5. #include <malloc.h>
  6. #include <string.h>
  7. #include <conio.h>
  8. #include <process.h>
  9. #include <graph.h>
  10.  
  11. /* kiss tnc routines for various  - HEP/RWM  */
  12.  
  13. int getbyte(),port,instat();
  14.  
  15. #define    FEND        0300    /* Frame End */
  16. #define    FESC        0333    /* Frame Escape */
  17. #define    TFEND        0334    /* Transposed frame end */
  18. #define    TFESC        0335    /* Transposed frame escape */
  19.  
  20.  
  21. #define SSIDMD    0x60
  22. #define SSIDMS    0x61
  23.  
  24. unsigned char pkt[300],echo=0;
  25. unsigned long time_out,now;
  26. unsigned char line[336],dump=0;
  27. unsigned char *in_buf;
  28. FILE *dumpr,*dumpa;
  29. union REGS inreg,outreg;
  30. struct tm *gmt;
  31. unsigned char satellite=4,com_str[]="COM1:9600,N,8,1",*satname[]={"PACSAT",
  32. "DOVE","WEBER","LUSAT"},newsat=0,rawdmp[40],ascdmp[40];
  33.  
  34. struct eqn {
  35.     unsigned char channel,name[16],units[9],ok,value;
  36.     float a0,a1,a2;
  37. } tlmval[80];
  38.  
  39. void asc_enab(),asc_disab();    
  40. main(argc,argv)
  41. int argc;
  42. char *argv[];
  43. {
  44.    int ch,frame_l,i;
  45.    long timeit,addr;
  46.    unsigned char *buf,*bufc;
  47.    void tlm(),status(),check_call(); 
  48.  
  49.    i=1;
  50.  
  51.  
  52.    while (argv[i] != NULL) {
  53.        *argv[i] = toupper(*argv[i]);
  54.        switch(*argv[i]) {
  55.         case 'C':{
  56.             strcpy(com_str,argv[i]);
  57.             break;
  58.         }
  59.         default : break;
  60.     }
  61.     i++;
  62.     }    
  63.  
  64.    /* Set up serial port */
  65.  
  66.    setcom(com_str);
  67.    _clearscreen(_GCLEARSCREEN);
  68.    main_men();
  69.    while(1) {
  70.     if (kbhit() != 0) {
  71.         ch = getch();
  72.         ch = toupper(ch);
  73.         switch(ch) {
  74.             case 'F':{
  75.                 if(dump) {
  76.                     dump = 0;
  77.                     fcloseall();
  78.                 }
  79.                 _settextwindow(1,1,25,80);
  80.             _clearscreen(_GCLEARSCREEN);
  81.                 _outtext("Input raw data file to read: ");
  82.                 scanf("%s",rawdmp);
  83.                 if ((dumpr = fopen(rawdmp,"rb")) == NULL) {
  84.                     _outtext("\nFile Not found. Strike a key");
  85.                     getch();
  86.                 main_men();
  87.                     break;
  88.                 }
  89.             _clearscreen(_GCLEARSCREEN);
  90.             _settextposition(1,70);
  91.             if (satellite != 4) _outtext(satname[satellite]);
  92.             else _outtext("      ");
  93.             _settextposition(25,55);
  94.             _outtext("Q=Quit,space to continue");
  95.             frame_l = 0;
  96.              while (frame_l != -1) {
  97.                 frame_l=dsk_frame(pkt,dumpr);
  98.                 if (frame_l < 0 ) {
  99.                     fclose(dumpr);
  100.                     _settextposition(25,55);
  101.                     while(kbhit() != 0) getch();
  102.                     _outtext("File end, strike a key  ");
  103.                     getch();
  104.                     break;
  105.                 }
  106.                 ax25r(pkt,frame_l);
  107.                 if (strstr(line,">TLM") != NULL) {
  108.                     check_call();
  109.                     tlm();
  110.                 } else if ((buf=strstr(line,"uptime")) != NULL) {
  111.                     _settextposition(1,1);
  112.                     _outtext(buf);
  113.                 }
  114.                 else if (strstr(line,">STATUS") != NULL) {
  115.                         check_call();
  116.                         status();
  117.                         frame_l = getch();
  118.                         if (toupper(frame_l) == 'Q') break;
  119.                 }
  120.                 if(newsat) {
  121.                     _settextposition(1,70);
  122.                        _outtext("       ");
  123.                     _settextposition(1,70);
  124.                        _outtext(satname[satellite]);
  125.                        newsat = 0;
  126.                 }
  127.             }
  128.             _clearscreen(_GCLEARSCREEN);
  129.             main_men();
  130.                 break;
  131.             }
  132.             case 'D': {
  133.                 if (dump == 0) {
  134.                     _settextwindow(1,1,25,80);
  135.                 _clearscreen(_GCLEARSCREEN);
  136.                     _outtext("Input raw data dump file: ");
  137.                     scanf("%s",rawdmp);
  138.                     _outtext("\nInput ascii dump file: ");
  139.                     scanf("%s",ascdmp);
  140.                     if (((dumpr = fopen(rawdmp,"ab")) == NULL) ||
  141.                        ((dumpa = fopen(ascdmp,"at")) == NULL)) {
  142.                            perror("Error opening files");
  143.                            dump = 0;
  144.                     } else     dump = 1;
  145.                        main_men();
  146.             } else {
  147.                 dump = 0;
  148.                 fcloseall();
  149.             }
  150.             break;
  151.         }
  152.         case 'Q': {
  153.             _clearscreen(_GCLEARSCREEN);
  154.             asc_disab(port);
  155.             fcloseall();
  156.             exit(0);
  157.         }
  158.         case 'U':{
  159.             _clearscreen(_GCLEARSCREEN);
  160.             system("command");
  161.             main_men();
  162.             break;
  163.         }
  164.         case 'T': {
  165.             _settextwindow(1,1,25,80);
  166.             _clearscreen(_GCLEARSCREEN);
  167.             _settextposition(1,70);
  168.             if (satellite != 4) _outtext(satname[satellite]);
  169.             else _outtext("       ");
  170.             _settextposition(25,60);
  171.             _outtext("Keystroke to Quit");
  172.             do {
  173.                 if (instat(port)){
  174.                 frame_l=rec_frame(pkt);
  175.                 if (frame_l != -1) {
  176.                   ax25r(pkt,frame_l);
  177.                   if (dump) {
  178.                     fputs(line,dumpa);
  179.                   }
  180.                   if (strstr(line,">TLM") != NULL) {
  181.                     check_call();
  182.                     tlm();
  183.                   } else  if (strstr(line,">STATUS") != NULL) {
  184.                     check_call();
  185.                     status();
  186.                   } else if ((in_buf=strstr(line,"uptime")) != NULL) {
  187.                     _settextposition(1,1);
  188.                     _outtext(in_buf);
  189.                   }
  190.                 }}
  191.                 if(newsat) {
  192.                     _settextposition(1,70);
  193.                        _outtext("       ");
  194.                     _settextposition(1,70);
  195.                        _outtext(satname[satellite]);
  196.                        newsat = 0;
  197.                 }
  198.             } while (kbhit() == 0);
  199.             if (getch() == 0) getch();
  200.             _clearscreen(_GCLEARSCREEN);
  201.             main_men();
  202.             break;
  203.         }
  204.          }
  205.     }
  206.     _settextwindow(1,1,24,80);
  207.     do {
  208.        if(newsat) {
  209.            _settextwindow(25,1,25,80);
  210.            _settextposition(1,1);
  211.                _outtext("       ");
  212.            _settextposition(1,1);
  213.                _outtext(satname[satellite]);
  214.                _settextwindow(1,1,24,80);
  215.                newsat = 0;
  216.           }
  217.        if (instat(port) != 0) {
  218.         _settextposition(24,1);
  219.         frame_l=rec_frame(pkt);
  220.         if (frame_l != -1) {
  221.             ax25r(pkt,frame_l);
  222.             check_call();
  223.             _outtext(line);
  224.             if (dump) fputs(line,dumpa);
  225.         }
  226.         }
  227.     }  while (kbhit() == 0);
  228.     }
  229. }
  230.  
  231. /* Decode the raw KISS frames which have been stored on DISK*/
  232.  
  233. int dsk_frame(ubuf,dat_file)
  234. unsigned char *ubuf;
  235. FILE *dat_file;
  236. {
  237.  
  238.     int c,frame_size;
  239.     unsigned char *buf;
  240.  
  241.     while((c=fgetc(dat_file)) != FEND) 
  242.       if (c == EOF) 
  243.         if (feof(dat_file)) return -1;
  244.  
  245. kludge_garb:
  246.  
  247.     buf=ubuf;
  248.     
  249.     while( (c = fgetc(dat_file)) == FEND) 
  250.       if (c == EOF) 
  251.         if (feof(dat_file)) return -1;
  252.  
  253.     c = fgetc(dat_file);  /* ignore KISS type code */
  254.     if (c == EOF) 
  255.       if(feof(dat_file)) return -1;
  256.     frame_size = 0;
  257.     do{
  258.         if(c == FESC){
  259.             c = fgetc(dat_file);
  260.             switch(c){
  261.                 case TFEND:
  262.                     *buf++ = FEND;
  263.                     frame_size++;
  264.                     break;
  265.  
  266.                 case TFESC:
  267.                     *buf++ = FESC;
  268.                     frame_size++;
  269.                     break;
  270.  
  271.                 default:
  272.                     break;
  273.             }
  274.         }
  275.         else{
  276.             if (c == EOF) 
  277.               if(feof(dat_file)) return -1;
  278.             *buf++ = c;
  279.             frame_size++;
  280.         }
  281.         c = fgetc(dat_file);
  282.     } while( c != FEND);
  283.  
  284.         /* If we get a short frame becuase the main loop doesn't read
  285.            except after it sends a command, go and restart this frame,
  286.            i.e., assume that the "end" is the start of a new frame. */
  287.  
  288.     if (frame_size<14) goto kludge_garb;
  289.     return frame_size;
  290. }
  291.  
  292.  
  293. /* Telemetry format routine */
  294.  
  295. static unsigned char *t;
  296.  
  297. void tlm()
  298. {
  299.     int a,b;
  300.     unsigned char *print_tlm();
  301.     if ((t=strchr(in_buf,':')) != NULL){
  302.         t=in_buf;
  303.     }
  304.     else return;
  305.     while (sscanf(t," %x:%x",&a,&b)==2) {
  306.         _settextposition(3+(a/3),(a%3)*26+1);
  307.         printf("%-25.25s   ",print_tlm(a,b));
  308.         t= t+6;
  309.     }
  310. }
  311.  
  312. /* Decode the telemetry from the tlm table values */
  313.  
  314. static unsigned char printit[40];
  315. unsigned char *print_tlm(chan,value)
  316. unsigned char chan,value;
  317. {
  318.     float fvalue;
  319.     struct eqn *ptr;
  320.     
  321.     ptr = &tlmval[chan];
  322.     if (ptr->ok == 1) {
  323.         ptr->value = value;
  324.         fvalue = value;
  325.         fvalue = fvalue * (fvalue * ptr->a2 + ptr->a1) + ptr->a0;
  326.         sprintf(printit,"%-14.14s %7.3f %c ",ptr->name,fvalue,ptr->units[0]);
  327.     } else *printit=0;
  328.     return printit;
  329. }
  330.  
  331.  
  332. /* Menu routine */
  333. main_men()
  334. {
  335.     _settextwindow(25,1,25,80);
  336.     _clearscreen(_GCLEARSCREEN);
  337.     if (satellite != 4) {
  338.         _settextposition(25,1);
  339.         _outtext(satname[satellite]);
  340.     }
  341.     _settextposition(1,10);
  342.     _outtext("D = Toggle Dump, T = Tlm Decode, F = Decode File, Q = Quit");
  343.     _settextwindow(1,1,24,80);
  344. }
  345.  
  346. /* Decode the status line from the telemetry */
  347.  
  348. void status()
  349. {
  350.     int tx,txp,bcr,sb;
  351.     _settextposition(25,1);
  352.     switch (satellite) {
  353.         case 0: {
  354.             sscanf(&in_buf[9]," %2X",&bcr);
  355.             sscanf(&in_buf[18]," %2X",&txp);
  356.             sscanf(&in_buf[21]," %2X",&tx);
  357.             sscanf(&in_buf[27]," %2X",&sb);
  358.             sprintf(line,"TXA:%1u TXB:%1u TX Pwr:%1X SbT:%1X BCR:%2X",
  359.                     1^(tx&1),1^((tx&2)>>1),txp&0xF,(sb>>7)^1,bcr);
  360.             _outtext(line);
  361.             break;
  362.         }
  363.         case 1 :{
  364.             sscanf(&in_buf[9]," %2X",&bcr);
  365.             sscanf(&in_buf[18]," %2X",&txp);
  366.             sscanf(&in_buf[21]," %2X",&tx);
  367.             sscanf(&in_buf[27]," %2X",&sb);
  368.             sprintf(line,"TXA:%1u TXB:%1u TX Pwr:%1X SbT:%1X BCR:%2X",
  369.                 (tx&1),((tx&2)>>1),txp&0xF,(sb>>7)^1,bcr);
  370.             _outtext(line);
  371.             break;
  372.         }
  373.         case 2: {
  374.             sscanf(&in_buf[9]," %2X",&bcr);
  375.             sscanf(&in_buf[18]," %2X",&txp);
  376.             sscanf(&in_buf[21]," %2X",&tx);
  377.             sprintf(line,"TXA:%1u TXB:%1u TX Pwr:%1X, BCR:%2X",
  378.                 1^(tx&1),1^((tx&2)>>1),txp&0xF,bcr);
  379.             _outtext(line);
  380.             break;
  381.         }
  382.         case 3: {
  383.             sscanf(&in_buf[9]," %2X",&bcr);
  384.             sscanf(&in_buf[18]," %2X",&txp);
  385.             sscanf(&in_buf[21]," %2X",&tx);
  386.             sprintf(line,"TXA:%1u TXB:%1u TX Pwr:%1X, BCR:%2X",
  387.                 1^(tx&1),1^((tx&2)>>1),txp&0xF,bcr);
  388.             _outtext(line);
  389.             break;
  390.         }
  391.     }
  392. }
  393.  
  394. /* Make sure we are decoding with the correct equations, if not, then
  395.    read in the appropriate file */
  396.    
  397. void check_call()
  398. {
  399.     FILE *tlm_dat;
  400.     unsigned char tmpsat,tlmline[81];
  401.     struct eqn *ptr;
  402.     for(tmpsat=0;tmpsat<4;tmpsat++) {
  403.       if(strstr(line,satname[tmpsat]) != NULL) {
  404.         if (tmpsat != satellite) {
  405.         satellite = tmpsat;
  406.         newsat = 1;
  407.         if((tlm_dat=fopen(satname[tmpsat],"rt")) == NULL) {
  408.             puts("OOPS, you forgot to leave those files around!");
  409.             fcloseall();
  410.             exit(0);
  411.         }
  412.         tmpsat = 0;
  413.         memset(tlmval,0,80*sizeof(tlmval[0]));
  414.         while (fgets(tlmline,80,tlm_dat) != NULL) {
  415.             ptr = &tlmval[tmpsat++];
  416.             sscanf(tlmline," %X",&ptr->channel);
  417.             strncpy(ptr->name,&tlmline[6],15);
  418.             *(strchr(ptr->name,':')) = 0;
  419.             ptr->name[15]=0;
  420.             sscanf(&tlmline[21]," %f",&ptr->a0);
  421.             sscanf(&tlmline[34]," %f",&ptr->a1);
  422.             sscanf(&tlmline[46]," %f",&ptr->a2);
  423.             sscanf(&tlmline[59],"%7s",ptr->units);
  424.             ptr->units[8]=0;
  425.             ptr->ok=1;
  426.         }
  427.         fclose(tlm_dat);
  428.          }
  429.          return;
  430.       }
  431.     }
  432. }
  433.  
  434.  
  435. /* Horrible AX.25 handler, receive only */
  436.  
  437. ax25r(frame,framel)
  438. unsigned char *frame;
  439. int framel;
  440. {
  441.   unsigned char *buf,*bufc,lineptr=0;
  442.   int i,j,k,endadr=0;
  443.  
  444.   buf = bufc = frame;
  445.   buf[framel]=0;
  446.   /* Find the end of the address field */
  447.   do {
  448.  
  449.   /* Fix up addresses and SSID's into readable form */
  450.  
  451.     /* Pick off the ssid from the shit in byte 7 of each address */
  452.     
  453.     k = bufc[6]&1;
  454.     bufc[6] = ((bufc[6] >> 1) & 0x0F);
  455.     if (bufc[6] < 10) bufc[6] += '0';
  456.     else bufc[6] += 'A'-10;
  457.  
  458.     /* Shift the bits where they belong in each character of the
  459.        address */
  460.  
  461.     for(i=0;i<6;i++) {
  462.       bufc[i] >>= 1;
  463.     }
  464.     bufc += 7;
  465.     endadr++;
  466.   }  while ( k == 0);
  467.  
  468.   /* Output header line */
  469.  
  470.   /* For each callsign field */
  471.  
  472.     /* Output a dash, SSID, and arrow pointing to direction, screw
  473.        the heard/digipeated bit */
  474.  
  475.     bufc = &buf[7];
  476.     for(j=0;j<6;j++) line[lineptr++] = bufc[j];
  477.     line[lineptr++] ='-';
  478.     line[lineptr++] = buf[13];
  479.     line[lineptr++] ='>';
  480.     for(j=0;j<6;j++) line[lineptr++] = buf[j];
  481.     line[lineptr++] ='-';
  482.     line[lineptr++] = buf[6];
  483.     line[lineptr++]=' ';
  484. /*    line[lineptr++]='V';
  485.     line[lineptr++]=' ';*/
  486.     /* Output the call and SSID of repeaters */
  487. /*    for(i=endadr-1,bufc=buf+(endadr-1)*7;i>=2;i--,bufc -= 7) {
  488.     for(j=0;j<6;j++) line[lineptr++] =bufc[j];
  489.         line[lineptr++] = '-';
  490.         line[lineptr++] = bufc[6];
  491.         line[lineptr++] = ' ';
  492.     }
  493.   line[lineptr++] = ' ';*/
  494.   /* Is it a U frame, I frame, or S frame ? */
  495.   buf = frame + 7*endadr;
  496.   switch((*buf) & 0x1) {
  497.   case 0 : { /* It is an I frame */
  498.     while ((bufc=strchr(&buf[2],'\r')) != NULL) *bufc = '\n';
  499.     sprintf(&line[lineptr],"NR=%1u P/F=%1u NS=%1u PID=%2X\n%s",
  500.              (unsigned) (((*buf)&0xE0)>>5),
  501.          (unsigned) (((*buf)&0x10)>>4),
  502.          (unsigned)(((*buf)&0xF)>>1),
  503.          (unsigned) buf[1],&buf[2]);
  504.          bufc = &line[strlen(line)-1];
  505.          if (*bufc != '\n') {
  506.              *(bufc+1) = '\n';
  507.         *(bufc+2) = 0;
  508.          }
  509.     break;
  510.   }
  511.   case 1: {
  512.     switch( (*buf) & 0x2) {
  513.     case 0: {
  514.       switch ((*buf) & 0xC) {
  515.       case 0: {
  516.     sprintf(&line[lineptr],"RR NR=%1u P/F=%1u\n",(unsigned) (((*buf) & 0xE0)>>5),
  517.            (unsigned) ((*buf) & 0x10)>>4);
  518.     break;
  519.       }
  520.       case 4: {
  521.     sprintf(&line[lineptr],"RNR NR=%1u P/F=%1u\n",(unsigned) (((*buf) & 0xE0)>>5),
  522.            (unsigned) ((*buf) & 0x10)>>4);
  523.     break;
  524.       }
  525.       case 8: {
  526.     sprintf(&line[lineptr],"REJ NR=%1u P/F=%1u\n",(unsigned) (((*buf) & 0xE0)>>5),
  527.            (unsigned) ((*buf) & 0x10)>>4);
  528.     break;
  529.       }
  530.       }
  531.       break;
  532.     }
  533.     case 2:{
  534.       switch(((*buf) & 0xE0)>>5) {
  535.       case 0 :{
  536.     if ((*buf & 0x0C) != 0) sprintf(&line[lineptr]," DM\n");
  537.     else {
  538.       while ((bufc=strchr(&buf[2],'\r')) != NULL) *bufc = '\n';
  539.       in_buf = &buf[2];
  540.       time(&now);
  541.       gmt = gmtime(&now);
  542.       sprintf(&line[lineptr],"%s%s",asctime(gmt),in_buf);
  543.       bufc = &line[strlen(line)-1];
  544.       if (*bufc != '\n') {
  545.           *(bufc+1) = '\n';
  546.         *(bufc+2) = 0;
  547.       }
  548.     }
  549.     break;
  550.       }
  551.       case 1: {
  552.     sprintf(&line[lineptr]," SABM\n");
  553.     break;
  554.       }
  555.       case 2: {
  556.     sprintf(&line[lineptr]," DISC\n");
  557.     break;
  558.       }
  559.       case 3: {
  560.     sprintf(&line[lineptr]," UA\n");
  561.     break;
  562.       }
  563.       case 4: {
  564.     sprintf(&line[lineptr]," FRMR");
  565.     break;
  566.       }
  567.       }
  568.       break;
  569.     }
  570.     }
  571.     break;
  572.   }
  573.   }
  574. }
  575.  
  576.  
  577. int rec_frame(ubuf)
  578. unsigned char *ubuf;
  579. {
  580.  
  581.     unsigned char c;
  582.     int frame_size;
  583.     unsigned char *buf;
  584.     time(&time_out);
  585.     time_out+=3;
  586.  
  587.     while(getbyte() != FEND) {
  588.         time(&now);
  589.         if (now>time_out) return -1;
  590.  
  591.     }
  592. kludge_garb:
  593.  
  594.     buf=ubuf;
  595.     /* wait for start of frame */
  596.     while( (c = getbyte()) == FEND) {
  597.         time(&now);
  598.         if (now>time_out) return -1;
  599.     }
  600.                     /* ignore any extra FENDS */
  601.     c = getbyte();  /* ignore KISS type code */
  602.     frame_size = 0;
  603.     do{
  604.         time(&now);
  605.         if (now>time_out) return -1;
  606.  
  607.         if(c == FESC){
  608.             c = getbyte();
  609.             switch(c){
  610.                 case TFEND:
  611.                     *buf++ = FEND;
  612.                     frame_size++;
  613.                     break;
  614.  
  615.                 case TFESC:
  616.                     *buf++ = FESC;
  617.                     frame_size++;
  618.                     break;
  619.  
  620.                 default:
  621.                     break;
  622.             }
  623.         }
  624.         else{
  625.             *buf++ = c;
  626.             frame_size++;
  627.         }
  628.         c = getbyte();
  629.     } while( c != FEND);
  630.  
  631.         /* If we get a short frame because the main loop doesn't read
  632.            except after it sends a command, go and restart this frame,
  633.            i.e., assume that the "end" is the start of a new frame. */
  634.  
  635.     if (frame_size<14) goto kludge_garb;
  636.     return frame_size;
  637.  
  638. }
  639.  
  640.  
  641.  
  642. /* Following serial io routines are taken from Quiktrak */
  643.  
  644.     
  645. static unsigned char b1[8] = { '1', '1', '3', '6', '1', '2', '4', '9' };
  646. static unsigned char b2[8] = { '1', '5', '0', '0', '2', '4', '8', '6' };
  647. static unsigned char pars[4] = { 'N', 'O', 'N', 'E' };
  648. static unsigned char stops[2] = { '1', '2' };
  649. static unsigned char wlens[4] = { '?', '?', '7', '8' };
  650.  
  651. /*setcom, sets up the COM port*/ 
  652. setcom(setstr)
  653. unsigned char *setstr;
  654. {
  655.   unsigned char *p;
  656.   int  baud, par, stop, wlen;
  657.   short ok;
  658.   union REGS inreg, outreg;
  659.  
  660.  
  661. /*
  662.  *  Command line to upper case.
  663.  */
  664.  
  665.   for (p = setstr; *p; p++) if (islower(*p)) *p = toupper(*p);
  666. /*
  667.  *  Find port number.
  668.  */
  669.  
  670.   for (p = setstr; *p && (*p != ':'); p++);
  671.   if (*p != ':') { 
  672.       error("No colon after COMn");
  673.       return;
  674.   }
  675.   port = (int) (*(p - 1) - '0') - 1;
  676.   if ((port < 0) || (port > 7)) {
  677.       error("Port number out of range");
  678.       return;
  679.   }
  680.   p++;
  681.   if (!*p) {
  682.       error("Parameters missing");
  683.       return;
  684.   }
  685.  
  686. /*
  687.  *  Find baud rate.
  688.  */
  689.  
  690.   ok = 0;
  691.   for (baud = 0; !ok && (baud < 8); baud++)
  692.   {
  693.     ok = (*p == b1[baud]) && (*(p + 1) == b2[baud]);
  694.   }
  695.   baud--;
  696.   if (!ok) {
  697.       error("Baud rate not correct");
  698.       return;
  699.   }
  700.   for (; *p && (*p != ','); p++);
  701.   if (!*p++) {
  702.       error("Missing parameter");
  703.       return;
  704.   }
  705.   if (!*p) {
  706.       error("Missing parameter");
  707.       return;
  708.   }
  709.  
  710. /*
  711.  *  Find parity.
  712.  */
  713.   ok = 0;
  714.   for (par = 0; !ok && (par < 4); par++)
  715.   {
  716.     ok = (pars[par] == *p);
  717.   }
  718.   par--;
  719.   if (!ok) {
  720.       error("Parity not N, E, or O");
  721.       return;
  722.   }
  723.   for (; *p && (*p != ','); p++);
  724.   if (!*p++) {
  725.       error("Missing parameter");
  726.       return;
  727.   }
  728.   if (!*p) {
  729.       error("Missing parameter");
  730.       return;
  731.   }
  732.  
  733. /*
  734.  *  Find word length.
  735.  */
  736.  
  737.   ok = 0;
  738.   for (wlen = 0; !ok && (wlen < 4); wlen++)
  739.   {
  740.     ok = (wlens[wlen] == *p);
  741.   }
  742.   wlen--;
  743.   if (!ok) {
  744.       error("Word length is not 7 or 8");
  745.       return;
  746.   }
  747.   for (; *p && (*p != ','); p++);
  748.   if (!*p++) {
  749.       error("Missing parameter");
  750.       return;
  751.   }
  752.   if (!*p) {
  753.       error("Missing parameter");
  754.       return;
  755.   }
  756. /*
  757.  *  Find number of stop bits.
  758.  */
  759.  
  760.   ok = 0;
  761.   for (stop = 0; !ok && (stop < 2); stop++)
  762.   {
  763.     ok = (stops[stop] == *p);
  764.   }
  765.   stop--;
  766.   if (!ok) {
  767.       error("Number of stop bits not 1 or 2");
  768.       return;
  769.   }
  770.  
  771. /* Compute control byte */
  772.   inreg.h.al = 32 * baud + 8 * par + 4 * stop + wlen;
  773.  
  774.   printf("     COM%d:%c%c,%c,%c,%c = %x\n", port + 1,
  775.     b1[baud], b2[baud], pars[par], wlens[wlen], stops[stop], inreg.h.al);
  776.  
  777.   inreg.x.dx = port;
  778.   inreg.h.ah = 0;
  779.   int86 (0x14, &inreg, &outreg);   /* Set the speed,etc using the BIOS */
  780.   asc_enab(port);           /* Turn on interrupt handler */
  781. }
  782.  
  783. int getbyte()
  784. {
  785.     int x;
  786.  
  787.     do{
  788.         time(&now);
  789.         if (now>time_out) return -1;
  790.  
  791.         else{
  792.             x = rcvbyte(port);
  793.         }
  794.     } while(x == -1);
  795.     x &= 0xff;
  796.     if (dump) fputc(x,dumpr);
  797.  
  798.     return x;
  799.  
  800. }
  801.  
  802.  
  803. error(str)
  804. char *str;
  805. {
  806.     perror(str);
  807.     exit(0);
  808. }
  809.  
  810.